1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gdk.Display;
26 
27 private import gdk.AppLaunchContext;
28 private import gdk.Clipboard;
29 private import gdk.Device;
30 private import gdk.Event;
31 private import gdk.GLContext;
32 private import gdk.MonitorGdk;
33 private import gdk.Seat;
34 private import gdk.Surface;
35 private import gdk.c.functions;
36 public  import gdk.c.types;
37 private import gio.ListModelIF;
38 private import glib.ErrorG;
39 private import glib.GException;
40 private import glib.ListG;
41 private import glib.Str;
42 private import glib.c.functions;
43 private import gobject.ObjectG;
44 private import gobject.Signals;
45 private import gobject.Value;
46 private import std.algorithm;
47 
48 
49 /**
50  * `GdkDisplay` objects are the GDK representation of a workstation.
51  * 
52  * Their purpose are two-fold:
53  * 
54  * - To manage and provide information about input devices (pointers, keyboards, etc)
55  * - To manage and provide information about output devices (monitors, projectors, etc)
56  * 
57  * Most of the input device handling has been factored out into separate
58  * [class@Gdk.Seat] objects. Every display has a one or more seats, which
59  * can be accessed with [method@Gdk.Display.get_default_seat] and
60  * [method@Gdk.Display.list_seats].
61  * 
62  * Output devices are represented by [class@Gdk.Monitor] objects, which can
63  * be accessed with [method@Gdk.Display.get_monitor_at_surface] and similar APIs.
64  */
65 public class Display : ObjectG
66 {
67 	/** the main Gtk struct */
68 	protected GdkDisplay* gdkDisplay;
69 
70 	/** Get the main Gtk struct */
71 	public GdkDisplay* getDisplayStruct(bool transferOwnership = false)
72 	{
73 		if (transferOwnership)
74 			ownedRef = false;
75 		return gdkDisplay;
76 	}
77 
78 	/** the main Gtk struct as a void* */
79 	protected override void* getStruct()
80 	{
81 		return cast(void*)gdkDisplay;
82 	}
83 
84 	/**
85 	 * Sets our main struct and passes it to the parent class.
86 	 */
87 	public this (GdkDisplay* gdkDisplay, bool ownedRef = false)
88 	{
89 		this.gdkDisplay = gdkDisplay;
90 		super(cast(GObject*)gdkDisplay, ownedRef);
91 	}
92 
93 
94 	/** */
95 	public static GType getType()
96 	{
97 		return gdk_display_get_type();
98 	}
99 
100 	/**
101 	 * Gets the default `GdkDisplay`.
102 	 *
103 	 * This is a convenience function for:
104 	 *
105 	 * gdk_display_manager_get_default_display (gdk_display_manager_get ())
106 	 *
107 	 * Returns: a `GdkDisplay`, or %NULL if
108 	 *     there is no default display
109 	 */
110 	public static Display getDefault()
111 	{
112 		auto __p = gdk_display_get_default();
113 
114 		if(__p is null)
115 		{
116 			return null;
117 		}
118 
119 		return ObjectG.getDObject!(Display)(cast(GdkDisplay*) __p);
120 	}
121 
122 	/**
123 	 * Opens a display.
124 	 *
125 	 * If opening the display fails, `NULL` is returned.
126 	 *
127 	 * Params:
128 	 *     displayName = the name of the display to open
129 	 *
130 	 * Returns: a `GdkDisplay`
131 	 */
132 	public static Display open(string displayName)
133 	{
134 		auto __p = gdk_display_open(Str.toStringz(displayName));
135 
136 		if(__p is null)
137 		{
138 			return null;
139 		}
140 
141 		return ObjectG.getDObject!(Display)(cast(GdkDisplay*) __p);
142 	}
143 
144 	/**
145 	 * Emits a short beep on @display
146 	 */
147 	public void beep()
148 	{
149 		gdk_display_beep(gdkDisplay);
150 	}
151 
152 	/**
153 	 * Closes the connection to the windowing system for the given display.
154 	 *
155 	 * This cleans up associated resources.
156 	 */
157 	public void close()
158 	{
159 		gdk_display_close(gdkDisplay);
160 	}
161 
162 	/**
163 	 * Creates a new `GdkGLContext` for the `GdkDisplay`.
164 	 *
165 	 * The context is disconnected from any particular surface or surface
166 	 * and cannot be used to draw to any surface. It can only be used to
167 	 * draw to non-surface framebuffers like textures.
168 	 *
169 	 * If the creation of the `GdkGLContext` failed, @error will be set.
170 	 * Before using the returned `GdkGLContext`, you will need to
171 	 * call [method@Gdk.GLContext.make_current] or [method@Gdk.GLContext.realize].
172 	 *
173 	 * Returns: the newly created `GdkGLContext`
174 	 *
175 	 * Since: 4.6
176 	 *
177 	 * Throws: GException on failure.
178 	 */
179 	public GLContext createGlContext()
180 	{
181 		GError* err = null;
182 
183 		auto __p = gdk_display_create_gl_context(gdkDisplay, &err);
184 
185 		if (err !is null)
186 		{
187 			throw new GException( new ErrorG(err) );
188 		}
189 
190 		if(__p is null)
191 		{
192 			return null;
193 		}
194 
195 		return ObjectG.getDObject!(GLContext)(cast(GdkGLContext*) __p, true);
196 	}
197 
198 	/**
199 	 * Returns %TRUE if there is an ongoing grab on @device for @display.
200 	 *
201 	 * Params:
202 	 *     device = a `GdkDevice`
203 	 *
204 	 * Returns: %TRUE if there is a grab in effect for @device.
205 	 */
206 	public bool deviceIsGrabbed(Device device)
207 	{
208 		return gdk_display_device_is_grabbed(gdkDisplay, (device is null) ? null : device.getDeviceStruct()) != 0;
209 	}
210 
211 	/**
212 	 * Flushes any requests queued for the windowing system.
213 	 *
214 	 * This happens automatically when the main loop blocks waiting for new events,
215 	 * but if your application is drawing without returning control to the main loop,
216 	 * you may need to call this function explicitly. A common case where this function
217 	 * needs to be called is when an application is executing drawing commands
218 	 * from a thread other than the thread where the main loop is running.
219 	 *
220 	 * This is most useful for X11. On windowing systems where requests are
221 	 * handled synchronously, this function will do nothing.
222 	 */
223 	public void flush()
224 	{
225 		gdk_display_flush(gdkDisplay);
226 	}
227 
228 	/**
229 	 * Returns a `GdkAppLaunchContext` suitable for launching
230 	 * applications on the given display.
231 	 *
232 	 * Returns: a new `GdkAppLaunchContext` for @display
233 	 */
234 	public AppLaunchContext getAppLaunchContext()
235 	{
236 		auto __p = gdk_display_get_app_launch_context(gdkDisplay);
237 
238 		if(__p is null)
239 		{
240 			return null;
241 		}
242 
243 		return ObjectG.getDObject!(AppLaunchContext)(cast(GdkAppLaunchContext*) __p, true);
244 	}
245 
246 	/**
247 	 * Gets the clipboard used for copy/paste operations.
248 	 *
249 	 * Returns: the display's clipboard
250 	 */
251 	public Clipboard getClipboard()
252 	{
253 		auto __p = gdk_display_get_clipboard(gdkDisplay);
254 
255 		if(__p is null)
256 		{
257 			return null;
258 		}
259 
260 		return ObjectG.getDObject!(Clipboard)(cast(GdkClipboard*) __p);
261 	}
262 
263 	/**
264 	 * Returns the default `GdkSeat` for this display.
265 	 *
266 	 * Note that a display may not have a seat. In this case,
267 	 * this function will return %NULL.
268 	 *
269 	 * Returns: the default seat.
270 	 */
271 	public Seat getDefaultSeat()
272 	{
273 		auto __p = gdk_display_get_default_seat(gdkDisplay);
274 
275 		if(__p is null)
276 		{
277 			return null;
278 		}
279 
280 		return ObjectG.getDObject!(Seat)(cast(GdkSeat*) __p);
281 	}
282 
283 	/**
284 	 * Gets the monitor in which the largest area of @surface
285 	 * resides.
286 	 *
287 	 * Returns a monitor close to @surface if it is outside
288 	 * of all monitors.
289 	 *
290 	 * Params:
291 	 *     surface = a `GdkSurface`
292 	 *
293 	 * Returns: the monitor with the largest
294 	 *     overlap with @surface
295 	 */
296 	public MonitorGdk getMonitorAtSurface(Surface surface)
297 	{
298 		auto __p = gdk_display_get_monitor_at_surface(gdkDisplay, (surface is null) ? null : surface.getSurfaceStruct());
299 
300 		if(__p is null)
301 		{
302 			return null;
303 		}
304 
305 		return ObjectG.getDObject!(MonitorGdk)(cast(GdkMonitor*) __p);
306 	}
307 
308 	/**
309 	 * Gets the list of monitors associated with this display.
310 	 *
311 	 * Subsequent calls to this function will always return the
312 	 * same list for the same display.
313 	 *
314 	 * You can listen to the GListModel::items-changed signal on
315 	 * this list to monitor changes to the monitor of this display.
316 	 *
317 	 * Returns: a `GListModel` of `GdkMonitor`
318 	 */
319 	public ListModelIF getMonitors()
320 	{
321 		auto __p = gdk_display_get_monitors(gdkDisplay);
322 
323 		if(__p is null)
324 		{
325 			return null;
326 		}
327 
328 		return ObjectG.getDObject!(ListModelIF)(cast(GListModel*) __p);
329 	}
330 
331 	/**
332 	 * Gets the name of the display.
333 	 *
334 	 * Returns: a string representing the display name. This string is owned
335 	 *     by GDK and should not be modified or freed.
336 	 */
337 	public string getName()
338 	{
339 		return Str.toString(gdk_display_get_name(gdkDisplay));
340 	}
341 
342 	/**
343 	 * Gets the clipboard used for the primary selection.
344 	 *
345 	 * On backends where the primary clipboard is not supported natively,
346 	 * GDK emulates this clipboard locally.
347 	 *
348 	 * Returns: the primary clipboard
349 	 */
350 	public Clipboard getPrimaryClipboard()
351 	{
352 		auto __p = gdk_display_get_primary_clipboard(gdkDisplay);
353 
354 		if(__p is null)
355 		{
356 			return null;
357 		}
358 
359 		return ObjectG.getDObject!(Clipboard)(cast(GdkClipboard*) __p);
360 	}
361 
362 	/**
363 	 * Retrieves a desktop-wide setting such as double-click time
364 	 * for the @display.
365 	 *
366 	 * Params:
367 	 *     name = the name of the setting
368 	 *     value = location to store the value of the setting
369 	 *
370 	 * Returns: %TRUE if the setting existed and a value was stored
371 	 *     in @value, %FALSE otherwise
372 	 */
373 	public bool getSetting(string name, Value value)
374 	{
375 		return gdk_display_get_setting(gdkDisplay, Str.toStringz(name), (value is null) ? null : value.getValueStruct()) != 0;
376 	}
377 
378 	/**
379 	 * Gets the startup notification ID for a Wayland display, or %NULL
380 	 * if no ID has been defined.
381 	 *
382 	 * Returns: the startup notification ID for @display
383 	 */
384 	public string getStartupNotificationId()
385 	{
386 		return Str.toString(gdk_display_get_startup_notification_id(gdkDisplay));
387 	}
388 
389 	/**
390 	 * Finds out if the display has been closed.
391 	 *
392 	 * Returns: %TRUE if the display is closed.
393 	 */
394 	public bool isClosed()
395 	{
396 		return gdk_display_is_closed(gdkDisplay) != 0;
397 	}
398 
399 	/**
400 	 * Returns whether surfaces can reasonably be expected to have
401 	 * their alpha channel drawn correctly on the screen.
402 	 *
403 	 * Check [method@Gdk.Display.is_rgba] for whether the display
404 	 * supports an alpha channel.
405 	 *
406 	 * On X11 this function returns whether a compositing manager is
407 	 * compositing on @display.
408 	 *
409 	 * On modern displays, this value is always %TRUE.
410 	 *
411 	 * Returns: Whether surfaces with RGBA visuals can reasonably
412 	 *     be expected to have their alpha channels drawn correctly
413 	 *     on the screen.
414 	 */
415 	public bool isComposited()
416 	{
417 		return gdk_display_is_composited(gdkDisplay) != 0;
418 	}
419 
420 	/**
421 	 * Returns whether surfaces on this @display are created with an
422 	 * alpha channel.
423 	 *
424 	 * Even if a %TRUE is returned, it is possible that the
425 	 * surface’s alpha channel won’t be honored when displaying the
426 	 * surface on the screen: in particular, for X an appropriate
427 	 * windowing manager and compositing manager must be running to
428 	 * provide appropriate display. Use [method@Gdk.Display.is_composited]
429 	 * to check if that is the case.
430 	 *
431 	 * On modern displays, this value is always %TRUE.
432 	 *
433 	 * Returns: %TRUE if surfaces are created with an alpha channel or
434 	 *     %FALSE if the display does not support this functionality.
435 	 */
436 	public bool isRgba()
437 	{
438 		return gdk_display_is_rgba(gdkDisplay) != 0;
439 	}
440 
441 	/**
442 	 * Returns the list of seats known to @display.
443 	 *
444 	 * Returns: the
445 	 *     list of seats known to the `GdkDisplay`
446 	 */
447 	public ListG listSeats()
448 	{
449 		auto __p = gdk_display_list_seats(gdkDisplay);
450 
451 		if(__p is null)
452 		{
453 			return null;
454 		}
455 
456 		return new ListG(cast(GList*) __p);
457 	}
458 
459 	/**
460 	 * Returns the keyvals bound to @keycode.
461 	 *
462 	 * The Nth `GdkKeymapKey` in @keys is bound to the Nth keyval in @keyvals.
463 	 *
464 	 * When a keycode is pressed by the user, the keyval from
465 	 * this list of entries is selected by considering the effective
466 	 * keyboard group and level.
467 	 *
468 	 * Free the returned arrays with g_free().
469 	 *
470 	 * Params:
471 	 *     keycode = a keycode
472 	 *     keys = return
473 	 *         location for array of `GdkKeymapKey`
474 	 *     keyvals = return
475 	 *         location for array of keyvals
476 	 *
477 	 * Returns: %TRUE if there were any entries
478 	 */
479 	public bool mapKeycode(uint keycode, out GdkKeymapKey[] keys, out uint[] keyvals)
480 	{
481 		GdkKeymapKey* outkeys;
482 		uint* outkeyvals;
483 		int nEntries;
484 
485 		auto __p = gdk_display_map_keycode(gdkDisplay, keycode, &outkeys, &outkeyvals, &nEntries) != 0;
486 
487 		keys = outkeys[0 .. nEntries];
488 		keyvals = outkeyvals[0 .. nEntries];
489 
490 		return __p;
491 	}
492 
493 	/**
494 	 * Obtains a list of keycode/group/level combinations that will
495 	 * generate @keyval.
496 	 *
497 	 * Groups and levels are two kinds of keyboard mode; in general, the level
498 	 * determines whether the top or bottom symbol on a key is used, and the
499 	 * group determines whether the left or right symbol is used.
500 	 *
501 	 * On US keyboards, the shift key changes the keyboard level, and there
502 	 * are no groups. A group switch key might convert a keyboard between
503 	 * Hebrew to English modes, for example.
504 	 *
505 	 * `GdkEventKey` contains a %group field that indicates the active
506 	 * keyboard group. The level is computed from the modifier mask.
507 	 *
508 	 * The returned array should be freed with g_free().
509 	 *
510 	 * Params:
511 	 *     keyval = a keyval, such as %GDK_KEY_a, %GDK_KEY_Up, %GDK_KEY_Return, etc.
512 	 *     keys = return location
513 	 *         for an array of `GdkKeymapKey`
514 	 *
515 	 * Returns: %TRUE if keys were found and returned
516 	 */
517 	public bool mapKeyval(uint keyval, out GdkKeymapKey[] keys)
518 	{
519 		GdkKeymapKey* outkeys;
520 		int nKeys;
521 
522 		auto __p = gdk_display_map_keyval(gdkDisplay, keyval, &outkeys, &nKeys) != 0;
523 
524 		keys = outkeys[0 .. nKeys];
525 
526 		return __p;
527 	}
528 
529 	/**
530 	 * Indicates to the GUI environment that the application has
531 	 * finished loading, using a given identifier.
532 	 *
533 	 * GTK will call this function automatically for [class@Gtk.Window]
534 	 * with custom startup-notification identifier unless
535 	 * [method@Gtk.Window.set_auto_startup_notification]
536 	 * is called to disable that feature.
537 	 *
538 	 * Params:
539 	 *     startupId = a startup-notification identifier, for which
540 	 *         notification process should be completed
541 	 */
542 	public void notifyStartupComplete(string startupId)
543 	{
544 		gdk_display_notify_startup_complete(gdkDisplay, Str.toStringz(startupId));
545 	}
546 
547 	/**
548 	 * Checks that OpenGL is available for @self and ensures that it is
549 	 * properly initialized.
550 	 * When this fails, an @error will be set describing the error and this
551 	 * function returns %FALSE.
552 	 *
553 	 * Note that even if this function succeeds, creating a `GdkGLContext`
554 	 * may still fail.
555 	 *
556 	 * This function is idempotent. Calling it multiple times will just
557 	 * return the same value or error.
558 	 *
559 	 * You never need to call this function, GDK will call it automatically
560 	 * as needed. But you can use it as a check when setting up code that
561 	 * might make use of OpenGL.
562 	 *
563 	 * Returns: %TRUE if the display supports OpenGL
564 	 *
565 	 * Since: 4.4
566 	 *
567 	 * Throws: GException on failure.
568 	 */
569 	public bool prepareGl()
570 	{
571 		GError* err = null;
572 
573 		auto __p = gdk_display_prepare_gl(gdkDisplay, &err) != 0;
574 
575 		if (err !is null)
576 		{
577 			throw new GException( new ErrorG(err) );
578 		}
579 
580 		return __p;
581 	}
582 
583 	/**
584 	 * Appends the given event onto the front of the event
585 	 * queue for @display.
586 	 *
587 	 * This function is only useful in very special situations
588 	 * and should not be used by applications.
589 	 *
590 	 * Params:
591 	 *     event = a `GdkEvent`
592 	 */
593 	public void putEvent(Event event)
594 	{
595 		gdk_display_put_event(gdkDisplay, (event is null) ? null : event.getEventStruct());
596 	}
597 
598 	/**
599 	 * Returns %TRUE if the display supports input shapes.
600 	 *
601 	 * This means that [method@Gdk.Surface.set_input_region] can
602 	 * be used to modify the input shape of surfaces on @display.
603 	 *
604 	 * On modern displays, this value is always %TRUE.
605 	 *
606 	 * Returns: %TRUE if surfaces with modified input shape are supported
607 	 */
608 	public bool supportsInputShapes()
609 	{
610 		return gdk_display_supports_input_shapes(gdkDisplay) != 0;
611 	}
612 
613 	/**
614 	 * Flushes any requests queued for the windowing system and waits until all
615 	 * requests have been handled.
616 	 *
617 	 * This is often used for making sure that the display is synchronized
618 	 * with the current state of the program. Calling [method@Gdk.Display.sync]
619 	 * before [method@GdkX11.Display.error_trap_pop] makes sure that any errors
620 	 * generated from earlier requests are handled before the error trap is removed.
621 	 *
622 	 * This is most useful for X11. On windowing systems where requests are
623 	 * handled synchronously, this function will do nothing.
624 	 */
625 	public void sync()
626 	{
627 		gdk_display_sync(gdkDisplay);
628 	}
629 
630 	/**
631 	 * Translates the contents of a `GdkEventKey` into a keyval, effective group,
632 	 * and level.
633 	 *
634 	 * Modifiers that affected the translation and are thus unavailable for
635 	 * application use are returned in @consumed_modifiers.
636 	 *
637 	 * The @effective_group is the group that was actually used for the
638 	 * translation; some keys such as Enter are not affected by the active
639 	 * keyboard group. The @level is derived from @state.
640 	 *
641 	 * @consumed_modifiers gives modifiers that should be masked out
642 	 * from @state when comparing this key press to a keyboard shortcut.
643 	 * For instance, on a US keyboard, the `plus` symbol is shifted, so
644 	 * when comparing a key press to a `<Control>plus` accelerator `<Shift>`
645 	 * should be masked out.
646 	 *
647 	 * This function should rarely be needed, since `GdkEventKey` already
648 	 * contains the translated keyval. It is exported for the benefit of
649 	 * virtualized test environments.
650 	 *
651 	 * Params:
652 	 *     keycode = a keycode
653 	 *     state = a modifier state
654 	 *     group = active keyboard group
655 	 *     keyval = return location for keyval
656 	 *     effectiveGroup = return location for effective group
657 	 *     level = return location for level
658 	 *     consumed = return location for modifiers that were used
659 	 *         to determine the group or level
660 	 *
661 	 * Returns: %TRUE if there was a keyval bound to keycode/state/group.
662 	 */
663 	public bool translateKey(uint keycode, GdkModifierType state, int group, out uint keyval, out int effectiveGroup, out int level, out GdkModifierType consumed)
664 	{
665 		return gdk_display_translate_key(gdkDisplay, keycode, state, group, &keyval, &effectiveGroup, &level, &consumed) != 0;
666 	}
667 
668 	/**
669 	 * Emitted when the connection to the windowing system for @display is closed.
670 	 *
671 	 * Params:
672 	 *     isError = %TRUE if the display was closed due to an error
673 	 */
674 	gulong addOnClosed(void delegate(bool, Display) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
675 	{
676 		return Signals.connect(this, "closed", dlg, connectFlags ^ ConnectFlags.SWAPPED);
677 	}
678 
679 	/**
680 	 * Emitted when the connection to the windowing system for @display is opened.
681 	 */
682 	gulong addOnOpened(void delegate(Display) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
683 	{
684 		return Signals.connect(this, "opened", dlg, connectFlags ^ ConnectFlags.SWAPPED);
685 	}
686 
687 	/**
688 	 * Emitted whenever a new seat is made known to the windowing system.
689 	 *
690 	 * Params:
691 	 *     seat = the seat that was just added
692 	 */
693 	gulong addOnSeatAdded(void delegate(Seat, Display) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
694 	{
695 		return Signals.connect(this, "seat-added", dlg, connectFlags ^ ConnectFlags.SWAPPED);
696 	}
697 
698 	/**
699 	 * Emitted whenever a seat is removed by the windowing system.
700 	 *
701 	 * Params:
702 	 *     seat = the seat that was just removed
703 	 */
704 	gulong addOnSeatRemoved(void delegate(Seat, Display) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
705 	{
706 		return Signals.connect(this, "seat-removed", dlg, connectFlags ^ ConnectFlags.SWAPPED);
707 	}
708 
709 	/**
710 	 * Emitted whenever a setting changes its value.
711 	 *
712 	 * Params:
713 	 *     setting = the name of the setting that changed
714 	 */
715 	gulong addOnSettingChanged(void delegate(string, Display) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
716 	{
717 		return Signals.connect(this, "setting-changed", dlg, connectFlags ^ ConnectFlags.SWAPPED);
718 	}
719 }